1593. Элегантно
переставленная сумма
Задана последовательность из n целых чисел {a1, a2,
…, an}. Необходимо найти
такую ее перестановку, для которой сумма модулей разниц всех соседних элементов
максимальна. Эту наибольшую сумму будем называть элегантной.
Рассмотрим, например,
последовательность {4, 2, 1, 5}. Искомой является перестановка {2, 5, 1, 4}, а
ее элегантная сумма равна |2 – 5| + |5 – 1| + |1 – 4| = 3 + 4 + 3 = 10. Для
всех других 24 перестановок значение элегантной суммы не больше 10.
Вход. Первая строка содержит количество
тестов t (t < 100). Каждая следующая строка является отдельным тестом.
Каждая входная строка начинается числом n
(1 < n < 51), за которым
следует последовательность из n неотрицательных чисел. Каждое число в последовательности не более 1000.
Выход. Для
каждого теста вывести его номер и значение элегантной суммы.
Пример входа |
Пример выхода |
3 4
4 2 1 5 4
1 1 1 1 2 10 1 |
Case
1: 10 Case
2: 0 Case 3: 9 |
жадный
алгоритм
Отсортируем
числа входной последовательности a. Создадим новый массив v, в котором будем строить искомую
перестановку. Изначально занесем в него минимальный и максимальный элементы
последовательности a (и соответственно эти элементы удалим из а). Элегантную сумму будем подсчитывать в переменной s. Сначала положим s = | v[0] – v[1] |.
Пока массив a
не пустой, жадным методом делаем наилучший выбор среди следующих четырех
возможностей:
1.
Наименьший элемент текущего массива а ставим в начало массива v.
2.
Наименьший элемент текущего массива а ставим в конец массива v.
3.
Наибольший элемент текущего массива а ставим в начало массива v.
4.
Наибольший элемент текущего массива а ставим в конец массива v.
Для каждого
случая пересчитываем новое значение s.
Совершаем тот выбор, для которого новое значение s будет наибольшим. Для каждого теста в качестве ответа выводим
значение s.
Поскольку
массивы a и v обновляются динамически, в качестве контейнеров будем
использовать двусторонние очереди.
Рассмотрим работу алгоритма на
первом тесте. Отсортируем массив:
a = {1, 2, 4,
5}
Шаг 1. Занесем в массив v наименьший и наибольший элементы: v = {1, 5}. Удалим их из
a, после чего a = {2, 4}.
Наименьший
и наибольший элементы массива а
приписываем справа и слева от массива v. Наибольшее значение суммы
достигается, например, на массиве {1, 5, 2}.
Шаг 2. v = {1, 5, 2}, a = {4}. В массиве a остался один
элемент. Приписываем его справа и слева от массива v. Пересчитываем суммы.
Искомая сумма равна 10,
достигается она например на перестановке
{4, 1, 5, 2}
Объявим рабочие очереди.
deque<int> a, v;
Читаем количество тестов tests.
scanf("%d", &tests);
for (i = 1; i <= tests; i++)
{
Начинаем обработку следующего
теста. Чистим содержимое массивов.
scanf("%d", &n);
a.clear();
v.clear();
Читаем входной массив а.
for (j = 0; j <
n; j++)
{
scanf("%d", &val);
a.push_back(val);
}
Сортируем входной массив.
sort(a.begin(),
a.end());
Заносим минимальный и
максимальный элементы последовательности a в массив v.
v.push_back(a.back());
v.push_front(a.front());
Положим изначально s = | v[1] – v[0] |.
s = abs(v.back()
- v.front());
Удаляем эти два элемента из
массива а.
a.pop_back();
a.pop_front();
Пока массив а не пустой, рассматриваем 4 случая и делаем среди них оптимальный
выбор жадным методом.
while (!a.empty())
{
Объявим целочисленный массив mx из четырех элементов.
mx[0] =
abs(v.front() - a.front());
mx[1] =
abs(v.back() - a.front());
mx[2] =
abs(v.front() - a.back());
mx[3] =
abs(v.back() - a.back());
rmax =
*max_element(mx, mx + 4);
if (rmax == mx[0])
{
v.push_front(a.front());
a.pop_front();
} else
if (rmax == mx[1])
{
v.push_back(a.front());
a.pop_front();
} else
if (rmax == mx[2])
{
v.push_front(a.back());
a.pop_back();
} else
{
v.push_back(a.back());
a.pop_back();
}
s += rmax;
}
Выводим ответ.
printf("Case %d:
%d\n", i, s);
}